﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Zero.UControl.Base.Models;

namespace Zero.UControl.Component
{
    /// <summary>
    /// CascaderSelector.xaml 的交互逻辑
    /// </summary>
    public partial class CascaderSelector : UserControl,INotifyPropertyChanged
    {

        public ObservableCollection<ObservableCollection<CascaderItem>> _columns { get; set; }
           = new ObservableCollection<ObservableCollection<CascaderItem>>();
        public CascaderSelector()
        {
            InitializeComponent();
            Loaded += BaseSelector_Loaded;
            Unloaded += BaseSelector_Unloaded;

            PART_TextBox.PreviewMouseLeftButtonUp += (s, e) => IsPopupOpen = true;
            PART_Columns.ItemsSource = _columns;
        }


        #region 依赖属性
        public ObservableCollection<CascaderItem> ItemsSource
        {
            get => (ObservableCollection<CascaderItem>)GetValue(ItemsSourceProperty);
            set => SetValue(ItemsSourceProperty, value);
        }

        public static readonly DependencyProperty ItemsSourceProperty =
            DependencyProperty.Register(nameof(ItemsSource), typeof(ObservableCollection<CascaderItem>), typeof(CascaderSelector),
                new PropertyMetadata(null, OnItemsSourceChanged));


        public string SelectedPathDisplay
        {
            get { return (string)GetValue(SelectedPathDisplayProperty); }
            set { SetValue(SelectedPathDisplayProperty, value); }
        }

        public static readonly DependencyProperty SelectedPathDisplayProperty =
            DependencyProperty.Register("SelectedPathDisplay", typeof(string), typeof(CascaderSelector),
                new PropertyMetadata(""));


        public ObservableCollection<CascaderItem> SelectedItems
        {
            get { return (ObservableCollection<CascaderItem>)GetValue(SelectedItemsProperty); }
            set { SetValue(SelectedItemsProperty, value); }
        }

        public static readonly DependencyProperty SelectedItemsProperty =
            DependencyProperty.Register("SelectedItems", typeof(ObservableCollection<CascaderItem>), typeof(CascaderSelector),
                new PropertyMetadata(new ObservableCollection<CascaderItem>()));


        public ObservableCollection<CascaderItem> FilteredItems
        {
            get { return (ObservableCollection<CascaderItem>)GetValue(FilteredItemsProperty); }
            set { SetValue(FilteredItemsProperty, value); }
        }

        public static readonly DependencyProperty FilteredItemsProperty =
            DependencyProperty.Register("FilteredItems", typeof(ObservableCollection<CascaderItem>), typeof(CascaderSelector),
                new PropertyMetadata(new ObservableCollection<CascaderItem>()));

        public bool IsMultiSelect
        {
            get => (bool)GetValue(IsMultiSelectProperty);
            set => SetValue(IsMultiSelectProperty, value);
        }

        public static readonly DependencyProperty IsMultiSelectProperty =
           DependencyProperty.Register("IsMultiSelect", typeof(bool), typeof(CascaderSelector), new PropertyMetadata(false, OnMultiSelectChanged));

        #endregion

        #region 普通属性

        private bool isPopupOpen;
        public bool IsPopupOpen
        {
            get => isPopupOpen;
            set
            {
                isPopupOpen = value;
                OnPropertyChanged(nameof(IsPopupOpen));
            }
        }
        #endregion

        #region 本地方法

        private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is CascaderSelector cascader)
            {
                if (cascader.ItemsSource.Count == 0) return;
                MultiSelectUpdate(cascader.ItemsSource, cascader.IsMultiSelect);
                cascader._columns.Clear();
                cascader._columns.Add(cascader.ItemsSource);
            }
        }

        private static void OnMultiSelectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if(d is CascaderSelector cascader)
            {
                if (cascader.ItemsSource != null && cascader.ItemsSource.Count != 0)
                {
                    MultiSelectUpdate(cascader.ItemsSource, cascader.IsMultiSelect);
                }
            }
        }

        private static void MultiSelectUpdate(IEnumerable<CascaderItem> cascaderItems,bool isMultiSelect)
        {
            foreach (var item in cascaderItems)
            {
                item.IsMultiSelect = isMultiSelect;
                if (item.HasChildren)
                {
                    MultiSelectUpdate(item.Children, isMultiSelect);
                }
            }
        }

        private void SearchBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (sender is TextBox tb)
            {
                string query = tb.Text.Trim();
                FilterItems(query);
            }
        }

        private void FilterItems(string keyword)
        {
            if (string.IsNullOrWhiteSpace(keyword))
            {
                FilteredItems = new ObservableCollection<CascaderItem>(ItemsSource);
                return;
            }

            var matches = ItemsSource
                .SelectMany(item => FilterRecursive(item, keyword))
                .ToList();

            FilteredItems = new ObservableCollection<CascaderItem>(matches);
        }

        private IEnumerable<CascaderItem> FilterRecursive(CascaderItem item, string keyword)
        {
            if (item.Label.Contains(keyword, StringComparison.InvariantCultureIgnoreCase))
                yield return item;

            foreach (var child in item.Children)
            {
                foreach (var match in FilterRecursive(child, keyword))
                    yield return match;
            }
        }

        public void UpdateSelectedPath()
        {
            if (IsMultiSelect)
            {
                SetCurrentValue(SelectedPathDisplayProperty,string.Join(", ", SelectedItems.Select(i => i.FullPath)));
            }
            else
            {
                SetCurrentValue(SelectedPathDisplayProperty,SelectedItems.FirstOrDefault()?.FullPath ?? "请选择");
            }
        }

        private void ToggleButton_Checked(object sender, RoutedEventArgs e)
        {
            if (sender is not ToggleButton toggle) return;
            bool isChecked = toggle.IsChecked.Value;
            CascaderItem? cascaderItem = toggle!.DataContext as CascaderItem;
            //UpdateParent(cascaderItem);
            // 找到当前是哪一列触发的
            var innerItemsControl = FindParent<ItemsControl>(toggle);
            var columnData = innerItemsControl?.DataContext as ObservableCollection<CascaderItem>;

            if (columnData != null)
            {
                int columnIndex = _columns.IndexOf(columnData);

                // 清除当前列之后的所有列
                while (_columns.Count > columnIndex + 1)
                    _columns.RemoveAt(_columns.Count - 1);

                // 添加子级列
                if (cascaderItem.Children != null && cascaderItem.Children.Any())
                {
                    _columns.Add(cascaderItem.Children);
                }
                else
                {
                    if (isChecked)
                    {
                        if (!IsMultiSelect)
                        {
                            SelectedItems.Clear();
                        }
                        SelectedItems.Add(cascaderItem);
                    }
                    else
                    {
                        SelectedItems.Remove(cascaderItem);
                    }
                }
            }
        }


        private void UpdateChildren(CascaderItem? cascaderItem)
        {
            var tempChildren = cascaderItem!.Children;
            if (tempChildren.Count == 0) return;

            foreach (var child in tempChildren)
            {
                child.IsChecked = cascaderItem.IsChecked;
                UpdateChildren(child);
            }
        }

        private void UpdateParent(CascaderItem? cascaderItem)
        {
            var tempParent = cascaderItem!.Parent;
            while (tempParent != null)
            {
                if (tempParent.Children.Any(c => c.IsChecked))
                {
                    if (!tempParent.IsChecked)
                        tempParent.IsChecked = true;
                }
                else
                {
                    if (tempParent.IsChecked)
                        tempParent.IsChecked = false;
                }
                tempParent = tempParent.Parent;
            }
        }

        private static T FindParent<T>(DependencyObject child) where T : DependencyObject
        {
            while (child != null)
            {
                if (child is T parent)
                    return parent;
                child = VisualTreeHelper.GetParent(child);
            }
            return null;
        }

        #endregion

        #region 事件方法
        private void BaseSelector_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            Application.Current.MainWindow.MouseDown += OnWindowMouseDown;
        }

        private void BaseSelector_Unloaded(object sender, System.Windows.RoutedEventArgs e)
        {
            Application.Current.MainWindow.MouseDown -= OnWindowMouseDown;
        }

        private void OnWindowMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (!IsPopupOpen)
                return;

            // 获取当前点击的元素
            var clickedElement = Mouse.DirectlyOver as DependencyObject;

            if (!IsDescendantOfThisControl(clickedElement))
            {
                IsPopupOpen = false;
            }
        }

        private void Reset_Button_Click(object sender, RoutedEventArgs e)
        {
            foreach (var item in SelectedItems)
            {
                item.IsChecked = false;
            }
            SelectedItems.Clear();
            UpdateSelectedPath();
        }

        private void Confirm_Button_Click(object sender, RoutedEventArgs e)
        {
            IsPopupOpen = false;
            UpdateSelectedPath();
        }
        #endregion

        // 判断元素是否是当前控件的子元素
        private bool IsDescendantOfThisControl(DependencyObject element)
        {
            while (element != null)
            {
                if (element == this)
                    return true;
                element = VisualTreeHelper.GetParent(element);
            }
            return false;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string prop) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
    }
}

